package com.coocaa.x.service.litedaemon;

import android.content.Context;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Looper;

import com.coocaa.x.framework.data.JObject;
import com.coocaa.x.framework.utils.LiteHandlerThread;
import com.coocaa.x.framework.utils.LogUtils;

import java.lang.Thread.UncaughtExceptionHandler;

public abstract class LiteDaemon {
    public static final String TAG = "LiteDaemon";
    public static final String DAEMON_ENTRY_META_DATA_NAME = "cc_daemon_entry";

    private static UncaughtExceptionHandler uncaughtExceptionHandler = new UncaughtExceptionHandler() {
        @Override
        public void uncaughtException(Thread thread, Throwable ex) {
            ex.printStackTrace();
        }
    };

    public static class LiteDaemonInfo extends JObject {
        public String id;
        public String name;
    }

    private HandlerThread handlerThread = null;
    private Handler handler = null;
    private LiteDaemonInfo info = null;
    protected Context mContext = null;

    public LiteDaemon(LiteDaemonInfo info) {
        this.info = info;
    }

    public final void setContext(Context context) {
        mContext = context;
    }

    public final synchronized void start() {
        if (handlerThread == null && handler == null) {
            handlerThread = new HandlerThread(info.name, android.os.Process.THREAD_PRIORITY_LOWEST) {
                @Override
                protected void onLooperPrepared() {
                    handler = new Handler(getLooper());
                    LogUtils.i(TAG, "LiteDaemon " + info.name + " onCreate!!");
                    onCreate(mContext);
                }
            };
            handlerThread.setUncaughtExceptionHandler(uncaughtExceptionHandler);
            handlerThread.start();
        }
    }

    public final synchronized void stop() {
        if (handlerThread != null && handler != null) {
            final Looper looper = handlerThread.getLooper();
            if (looper != null) {
                post(new Runnable() {
                    @Override
                    public void run() {
                        LogUtils.i(TAG, "LiteDaemon " + info.name + " onDestroy!!");
                        onDestroy();
                        looper.quit();
                    }
                });
            }
            handlerThread = null;
            handler = null;
        }
    }

    public final boolean post(final Runnable r) {
        return handler.post(new Runnable() {
            @Override
            public void run() {
                try {
                    r.run();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    public final boolean postDelayed(final Runnable r, long delayMillis) {
        return handler.postDelayed(new Runnable() {
            @Override
            public void run() {
                try {
                    r.run();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }, delayMillis);
    }

    public final void postOnUiThread(Runnable r) {
        LiteHandlerThread.postOnUiThread(r);
    }

    public final LiteDaemonInfo getInfo() {
        return info;
    }

    protected abstract void onCreate(Context context);

    protected abstract void onDestroy();
}
